from rest_framework import serializers

# 关联对象的序列化器
from apps.books.models import BookInfo, HeroInfo
'''继承serializers.Serializer的序列化器(最原始的)'''
# 关联对象的序列化器
class HeroRelatedSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    btitle = serializers.CharField()
# 图书序列化器创建  实例化后可得到属性
class BookSerializer(serializers.Serializer):
    id=serializers.IntegerField(required=True)
    btitle=serializers.CharField(required=True)
    bpub_date=serializers.DateField(required=True)
    # 1.主键输出   (参数为设置为只读模式)
    # heros = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
    # # 2.输出字符串
    # heros = serializers.StringRelatedField(read_only=True,many=True)
    # # 3.使用关联对象的序列化器(输出字典)
    # heros = HeroRelatedSerializer(read_only=True,many=True)
    # 方法名必须有validate  自条件定义方法判断前端数据是否符合
    # 检验时会自动调用(单个属性)
    # def validate_btitle(self,value):
    #     if "django" not  in value:
    #         raise serializers.ValidationError("必须是关于django的图书")
    #     return value
    # # 多属性时  方法名固定为validate  将多个值对比
    # # 也可以取多个值
    # def validate(self, attrs):
    #     # attrs为请求字典   默认值为0
    #     bread = attrs.get("bread",0)
    #     bcomment = attrs.get('bcomment',0)
    #     if bread >= bcomment:
    #         raise serializers.ValidationError("阅读量必须大于评论量")
    #     return attrs
    #     创建
    def create(self, validated_data):
        # validated_data通过验证后的字典
        book = BookInfo.objects.create(**validated_data)
        # 返回新建的实例
        return book
        # 修改
    def update(self, instance, validated_data):
        # instance需要修改的原始对象
        # validated_data通过验证后的字典
        # 返回修改的实例
        instance.btitle=validated_data.get("btitle")
        instance.bpub_date=validated_data.get("bpub_date")
        if "bread"in validated_data:
            instance.bread = validated_data.get("bread")
        if "bcomment"in validated_data:
            instance.bcomment = validated_data.get("bcomment")
        instance.save()
        return instance

'''继承serializers.ModelSerializer的序列化器(最原始的)'''
# 自定义关系模型类
class HeroModelRelatedSerializer(serializers.ModelSerializer):
    class Meta:
        model = HeroInfo
        fields =("id","hname")
# 模型类序列化器
class BookModelSerializer(serializers.ModelSerializer):
    # 图书数据序列化器属性相关使用   外建必须设置只读read_only  得到查询集时写many
    heroinfo_set = HeroModelRelatedSerializer(read_only=True,many=True)
    class Meta:
        model = BookInfo
        # # 取所有
        # fields = '__all__'
        # 取部分
        # fields = ["id", "btitle","heroinfo_set","bpub_date", 'bread', 'bcomment']
        fields = ["id", "btitle","heroinfo_set","bpub_date"]
        # 增加只读
        # read_only_fields = ["id"]
        # 1.增加额外约束   只对fields显示的字段有效
        extra_kwargs ={
            'bread': {'min_value': 10, 'required': True},
            'bcomment': {'min_value': 10, 'required': True},
            'heroinfo_set':{'required': False}}
        # # # 2.增加额外约束
        # def validate_btitle(self,value):
        #     return value

# 关联对象的序列化器
class BookModelRelatedSerializer(serializers.ModelSerializer):
    class Meta:
        model = BookInfo
        fields =["id","btitle"]

class HeroModelSerializer(serializers.ModelSerializer):
    hbook = BookModelRelatedSerializer(read_only=True)
    hbook_id=serializers.IntegerField()
    class Meta:
        model = HeroInfo
        fields = "__all__"














# 关联对象的序列化器
class BookRelatedSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    btitle = serializers.CharField()

class HeroSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    hname = serializers.CharField()
    hgender = serializers.IntegerField()
    hcomment = serializers.CharField()
    # 隐藏的关系属性,表示图书主键===>int
    # hbook_id = serializers.IntegerField()
    # 关系属性hbook===>BookInfo实例

# 输出关系属性(外建)的三种方法(1对n中n的关系属性的输出方案)
#     # 1.主键输出输出主键id   (参数为设置为只读模式)
#     hbook = serializers.PrimaryKeyRelatedField(read_only=True)
    # 2.输出字符串(名字)
    hbook = serializers.StringRelatedField(read_only=True)
#     # 3.使用关联对象的序列化器(输出自定义字典)
#     hbook = BookRelatedSerializer(read_only=True)
    def create(self, validated_data):
        # validated_data通过验证后的字典
        book = HeroInfo.objects.create(**validated_data)
        # 返回新建的实例
        return book
        # 修改
    def update(self, instance, validated_data):
        # instance需要修改的原始对象
        # validated_data通过验证后的字典
        # 返回修改的实例
        instance.btitle=validated_data.get("btitle")
        instance.bpub_date=validated_data.get("bpub_date")
        if "bread"in validated_data:
            instance.bread = validated_data.get("bread")
        if "bcomment"in validated_data:
            instance.bcomment = validated_data.get("bcomment")
        instance.save()
        return instance



# # 英雄序列化创建
# class HeroSerializer(serializers.Serializer):
#     id = serializers.IntegerField()
#     # hname = serializers.CharField(min_length=3,required=True,error_messages={"min_length":"名字最小长度为3","required":"必填项目"})
#     hname = serializers.CharField()
#     hgender = serializers.IntegerField()
#     hcomment = serializers.CharField()
#     # 隐藏的关系属性,表示图书主键===>int
#     # hbook_id = serializers.IntegerField()
#     # 关系属性hbook===>BookInfo实例
#
# # def validate_btitle(self,value):
# #     if "django" not  in value:
# #         raise serializers.ValidationError("必须是关于django的图书")
# #     return value
# # # 多属性时  方法名固定为validate  将多个值对比
# # # 也可以取多个值
# # def validate(self, attrs):
# #     # attrs为请求字典   默认值为0
# #     bread = attrs.get("bread",0)
# #     bcomment = attrs.get('bcomment',0)
# #     if bread >= bcomment:
# #         raise serializers.ValidationError("阅读量必须大于评论量")
# #     return attrs


